{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.6352719 ,  1.16152448, -0.30933178],\n",
       "       [-0.38738777,  0.11182895, -0.12461314]])"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# N 维数组对象 ndarray ，该对象是一个快速而灵活的大数据集容器\n",
    "# 利用这种数组对象对整块数据执行数学运算，如同标量运算一样\n",
    "# 关键理解，如何利用与标量值类似的语法进行批次计算\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "# Generate some random data\n",
    "data = np.random.randn(2, 3)\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-6.35271901, 11.61524475, -3.09331783],\n",
       "       [-3.87387771,  1.11828953, -1.24613137]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 批量进行数学运算\n",
    "data * 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.2705438 ,  2.32304895, -0.61866357],\n",
       "       [-0.77477554,  0.22365791, -0.24922627]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data + data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(2, 3)\n",
      "float64\n"
     ]
    }
   ],
   "source": [
    "# ndarray 是一个通用的同构数据多维容器，所有元素必须相同类型\n",
    "# 每一个 ndarray 数组 都有 shape，表示其维度大小的元组\n",
    "# 每一个 ndarray 数组 都有 dtype，表示其数据类型的对象\n",
    "\n",
    "print(data.shape)\n",
    "print(data.dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([6, 7, 5, 8, 0, 1])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 创建 ndarray\n",
    "\n",
    "# first, using the function of array\n",
    "# 接受任何序列类型，包括数组，产生新的含有传入数据的 ndarray 数组\n",
    "data_list = [6, 7, 5, 8, 0, 1]\n",
    "data_ndarray = np.array(data_list)\n",
    "data_ndarray"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3, 4],\n",
       "       [5, 6, 7, 8]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 嵌套序列，则被转换为 ndarray 多维数组\n",
    "data_list2 =  [[1, 2, 3, 4], [5, 6, 7, 8]]\n",
    "data_ndarray2 = np.array(data_list2)\n",
    "data_ndarray2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# second, using the function of zeros and ones and empty and eye\n",
    "# 传入参数，表示 数组形状（维度）的元组即可\n",
    "\n",
    "np.zeros(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 1., 1., 1., 1., 1.],\n",
       "       [1., 1., 1., 1., 1., 1.],\n",
       "       [1., 1., 1., 1., 1., 1.]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.ones((3,6))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[4.6e-322, 0.0e+000],\n",
       "        [0.0e+000, 0.0e+000],\n",
       "        [0.0e+000, 0.0e+000]],\n",
       "\n",
       "       [[0.0e+000, 0.0e+000],\n",
       "        [0.0e+000, 0.0e+000],\n",
       "        [0.0e+000, 0.0e+000]]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 返回值都是一些为初始化的“垃圾数据”\n",
    "np.empty((2,3,2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 0., 0.],\n",
       "       [0., 1., 0.],\n",
       "       [0., 0., 1.]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 方阵的单位矩阵\n",
    "np.eye(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 3 4 5 6 7 8 9]\n",
      "range(0, 10)\n"
     ]
    }
   ],
   "source": [
    "# arange 是 Python 内置函数 range 的数组版本\n",
    "print(np.arange(10))\n",
    "print(range(10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "float64\n",
      "int32\n"
     ]
    }
   ],
   "source": [
    "# dtype 在多数情况下，直接映射到响应的机器表示、\n",
    "# 这使得 “ 读写磁盘二进制数据流 ” 和 “ 集成 C 代码 ” 更加简单高效\n",
    "# 需要知道处理的数据，其类型是：浮点型、复数、整数、布尔值、字符串、普通Python对象\n",
    "# 控制数据在内存和磁盘中的储存方式，尤其是 大数据集\n",
    "\n",
    "# dtype 命名方式：类型名 + 用于表示元素 “ 位长 ” 的数字， 如：float64\n",
    "# 通过 dtype 显示指定 数据的类型\n",
    "# 通过 astype 方法明确将 ndarray 数组从一个 dtype 转换为另一个 dtype\n",
    "# astype 总会创建一个新的 ndarray 数组（数据的备份），即使两者 dtype 一致\n",
    "float_arr = np.array([1, 2, 3, 4, 5], dtype = np.float64)\n",
    "print(float_arr.dtype)\n",
    "int_arr = float_arr.astype(np.int32)\n",
    "print(int_arr.dtype)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1. 2. 3.]\n",
      " [4. 5. 6.]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[ 1.,  4.,  9.],\n",
       "       [16., 25., 36.]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# ndarray 数组，使得不需要循环即可对数据执行批量运算，故此称其矢量化 （vectorization）\n",
    "# 大小相等的数组之间任何算术运算都会应用到元素级\n",
    "arr = np.array([[1., 2., 3.], [4., 5., 6.]])\n",
    "print(arr)\n",
    "arr * arr\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1.        , 0.5       , 0.33333333],\n",
       "       [0.25      , 0.2       , 0.16666667]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# ndarray 数组与标量运算将标量值传播到每一个元素\n",
    "1 / arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "arr2 = np.array([[0., 4., 1.], [7., 2., 12.]])\n",
    "# 大小相同数组之间比较生成布尔值 ndarray 数组\n",
    "arr_bool = arr2 > arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dtype('bool')"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr_bool.dtype"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([7, 8, 9])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 不同大小 ndarray 数组之间运算 就称之为 广播\n",
    "# 更加高级的需求，需要对 广播机制 有着深刻的理解\n",
    "\n",
    "# 基本索引和切片\n",
    "# 对于一维数组 np.arange(n) 索引和切片与列表类似\n",
    "\n",
    "# 对于多维数组 np.array((m, n)) \n",
    "# 索引位置上的元素不再是标量，而是一维数组\n",
    "# 二维数组 axis 0 代表着 行 ， axis 1 代表着 列\n",
    "\n",
    "# 数组切片是原始数组的视图，也就是说数据不是复制的，视图上任意修改都会直接反映到源数组上\n",
    "# 这也就是处理大数据时，性能和内存 问题\n",
    "# 如果需要一份副本，需要明确进行复制操作 copy()\n",
    "\n",
    "arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n",
    "arr2d[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr2d[0][2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr2d[0, 2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [4, 5, 6],\n",
       "       [7, 8, 9]])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# ndarray 切片语法 与列表类似\n",
    "arr2d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [4, 5, 6]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 沿着 axis 0 进行切片\n",
    "arr2d[:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2, 3],\n",
       "       [5, 6]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 如同索引一样，可以传入多个切片\n",
    "arr2d[:2, 1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([4, 5])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 通过 整数索引 和 切片 混合，便可以得到低维度的切片\n",
    "arr2d[1, :2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 6])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr2d[:2, 2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1],\n",
       "       [4],\n",
       "       [7]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 只有冒号，表示取整个轴 \n",
    "# 前一个冒号，取轴 axis0 就是所有行\n",
    "# 后一个冒号，取轴 axis1 就是所有列\n",
    "arr2d[:, :1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr2d[:1, :]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0, 0],\n",
       "       [4, 0, 0],\n",
       "       [7, 8, 9]])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对于 取片 的赋值操作，会被扩散到整个选区\n",
    "# 只是一个视图，类似指针传递，而不是值传递（拷贝）\n",
    "arr2d[:2, 1:] = 0\n",
    "arr2d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Bob' 'Joe' 'Will' 'Bob' 'Will' 'Joe' 'Joe']\n",
      "[[-9.14571327e-01 -1.14708701e+00  1.82556264e+00  1.09181306e+00]\n",
      " [ 1.68295624e+00  1.33967931e+00  1.40242592e+00  8.45205553e-01]\n",
      " [-1.03529054e-01 -7.11220259e-01  3.81354758e-01  4.22864932e-01]\n",
      " [-1.09987175e+00 -3.91538227e-04  1.66008926e+00  1.51977012e-01]\n",
      " [-8.98916170e-01 -5.57088007e-01 -5.60297983e-01 -1.46818127e-01]\n",
      " [-6.54497458e-01 -7.92204383e-02 -1.10225781e+00  1.65243850e+00]\n",
      " [ 1.79779380e+00  1.40488501e+00 -1.51334745e-01  1.48714618e+00]]\n"
     ]
    }
   ],
   "source": [
    "names = np.array(['Bob', 'Joe', 'Will', 'Bob', 'Will', 'Joe', 'Joe'])\n",
    "data = np.random.randn(7, 4)\n",
    "\n",
    "print(names)\n",
    "print(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True, False, False,  True, False, False, False])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 每个名字都对应data数组中的一行， 而我们想要选出对应于名字\"Bob\"的所有行\n",
    "# 跟算术运算一样，数组的比较运算（如==） 也是矢量化的\n",
    "# 对names和字符串\"Bob\"的比较运算将会产生一个布尔型数组\n",
    "names == 'Bob'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-9.14571327e-01, -1.14708701e+00,  1.82556264e+00,\n",
       "         1.09181306e+00],\n",
       "       [-1.09987175e+00, -3.91538227e-04,  1.66008926e+00,\n",
       "         1.51977012e-01]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 利用这个 bool 索引即可完成以上需求\n",
    "data[names == 'Bob']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1.82556264, 1.09181306],\n",
       "       [1.66008926, 0.15197701]])"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 布尔型数组的长度必须跟被索引的轴长度一致\n",
    "# 可将布尔型数组跟切片、整数 混合使用\n",
    "data[names == 'Bob', 2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-9.14571327e-01, -1.14708701e+00,  1.82556264e+00,\n",
       "         1.09181306e+00],\n",
       "       [-1.09987175e+00, -3.91538227e-04,  1.66008926e+00,\n",
       "         1.51977012e-01]])"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# ~ 操作符用来反转条件很好用\n",
    "condition = names == 'Bob'\n",
    "data[condition]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.68295624,  1.33967931,  1.40242592,  0.84520555],\n",
       "       [-0.10352905, -0.71122026,  0.38135476,  0.42286493],\n",
       "       [-0.89891617, -0.55708801, -0.56029798, -0.14681813],\n",
       "       [-0.65449746, -0.07922044, -1.10225781,  1.6524385 ],\n",
       "       [ 1.7977938 ,  1.40488501, -0.15133474,  1.48714618]])"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data[~condition]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0., 0., 0., 0.],\n",
       "       [1., 1., 1., 1.],\n",
       "       [2., 2., 2., 2.],\n",
       "       [3., 3., 3., 3.],\n",
       "       [4., 4., 4., 4.],\n",
       "       [5., 5., 5., 5.],\n",
       "       [6., 6., 6., 6.],\n",
       "       [7., 7., 7., 7.]])"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 布尔条件：& | ~ \n",
    "# 通过布尔索引选取数组中数据，总是创建数据的副本，即使一模一样的数组\n",
    "\n",
    "# 花式索引\n",
    "# numpy 的一个术语\n",
    "arr = np.empty((8, 4))\n",
    "for i in range(8):\n",
    "    arr[i] = i\n",
    "\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[4., 4., 4., 4.],\n",
       "       [3., 3., 3., 3.],\n",
       "       [0., 0., 0., 0.],\n",
       "       [6., 6., 6., 6.]])"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 为了特定顺序选取 行子集 \n",
    "arr[[4, 3, 0, 6]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[5., 5., 5., 5.],\n",
       "       [3., 3., 3., 3.],\n",
       "       [1., 1., 1., 1.]])"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 使用 负数 索引\n",
    "arr[[-3, -5, -7]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2,  3],\n",
       "       [ 4,  5,  6,  7],\n",
       "       [ 8,  9, 10, 11],\n",
       "       [12, 13, 14, 15],\n",
       "       [16, 17, 18, 19],\n",
       "       [20, 21, 22, 23],\n",
       "       [24, 25, 26, 27],\n",
       "       [28, 29, 30, 31]])"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 一次传入多个索引数组，返回一个一维数组，其中元素对应各个 索引元组\n",
    "arr2 = np.arange(32).reshape((8, 4))\n",
    "arr2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 4, 23, 29, 10])"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr2[[1, 5, 7, 2], [0, 3, 1, 2]]\n",
    "# 索引元组 (1,0) (5,3) (7,1) (2,2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 4,  7,  5,  6],\n",
       "       [20, 23, 21, 22],\n",
       "       [28, 31, 29, 30],\n",
       "       [ 8, 11,  9, 10]])"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选取矩阵的 行列子集 是一个矩形区域\n",
    "arr2[[1, 5, 7, 2]][:, [0, 3, 1, 2]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  1,  2,  3,  4],\n",
       "       [ 5,  6,  7,  8,  9],\n",
       "       [10, 11, 12, 13, 14]])"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 数组转置 和 轴对换\n",
    "\n",
    "# ndarray 有 transpose 方法 和 特殊属性 T，进行转置\n",
    "arr = np.arange(15).reshape((3, 5))\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  5, 10],\n",
       "       [ 1,  6, 11],\n",
       "       [ 2,  7, 12],\n",
       "       [ 3,  8, 13],\n",
       "       [ 4,  9, 14]])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0,  5, 10],\n",
       "       [ 1,  6, 11],\n",
       "       [ 2,  7, 12],\n",
       "       [ 3,  8, 13],\n",
       "       [ 4,  9, 14]])"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.transpose()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 2.34795053,  0.15244923, -0.32459969],\n",
       "       [ 0.15244923, 14.88168017, -6.34881276],\n",
       "       [-0.32459969, -6.34881276,  3.8877473 ]])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 矩阵计算，矩阵内积，需要转置操作\n",
    "arr_dot = np.random.randn(6, 3)\n",
    "np.dot(arr_dot.T, arr_dot)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7]],\n",
       "\n",
       "       [[ 8,  9, 10, 11],\n",
       "        [12, 13, 14, 15]]])"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 对于高维数组，转置 transpose 需要接受一个 轴编号 的元组才能完成轴的转置\n",
    "arr = np.arange(16).reshape((2, 2, 4))\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  1,  2,  3],\n",
       "        [ 8,  9, 10, 11]],\n",
       "\n",
       "       [[ 4,  5,  6,  7],\n",
       "        [12, 13, 14, 15]]])"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将 axis0 换为 axis1，将 axis1 换为 axis0 ，axis2 保持不变\n",
    "arr.transpose((1, 0, 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  1,  2,  3],\n",
       "        [ 4,  5,  6,  7]],\n",
       "\n",
       "       [[ 8,  9, 10, 11],\n",
       "        [12, 13, 14, 15]]])"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 二维的转置，采用 .T 属性即可，其实就是进行轴对换\n",
    "# ndarray 还有 swapaxes 方法，需要接受 一对轴编号\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[[ 0,  4],\n",
       "        [ 1,  5],\n",
       "        [ 2,  6],\n",
       "        [ 3,  7]],\n",
       "\n",
       "       [[ 8, 12],\n",
       "        [ 9, 13],\n",
       "        [10, 14],\n",
       "        [11, 15]]])"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arr.swapaxes(1, 2)\n",
    "# 转置 和 轴对换 都是视图操作\n",
    "# 不会进行任何复制操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 通用函数 ： 快速的元素级数组函数\n",
    "# np.sqrt 开根号、    np.exp 指数函数、\n",
    "# np.square 平方、    np.abs 整数绝对值、 np.fabs 浮点数绝对值\n",
    "# np.sign 符号函数 计算元素的 正、 零、 负\n",
    "# np.log，np.log10，np.log2，np.log1p 对数函数\n",
    "# np.cos，np.sin，np.cosh, np.sinh 三角函数\n",
    "# np.arccos\\np.arcsin\\np.arccosh 反三角函数\n",
    "arr = np.arange(10)\n",
    "arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.00000000e+00, 2.71828183e+00, 7.38905610e+00, 2.00855369e+01,\n",
       "       5.45981500e+01, 1.48413159e+02, 4.03428793e+02, 1.09663316e+03,\n",
       "       2.98095799e+03, 8.10308393e+03])"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.exp(arr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
